home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianFontSystem.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  12KB  |  553 lines

  1. /*    ScianFontSystem.c
  2.     Routines for font system and string utilities
  3.  
  4.     Jim Lyons
  5.     7/26/91
  6.  
  7.     9/24/91 added support for raster fonts
  8.     1/5/92    EMP added font counting for both types of fonts
  9.     1/28/92    modified StrWidth and DrawString to handle tabs
  10.     4/6/92    added PostScript drawing mode 
  11.     9/14/92 changed DrawString to take alignment parameter
  12.         and changed name to DrawAString
  13.     9/10/93 added SetUIFont
  14. */
  15.  
  16. #include "Scian.h"
  17. #include "ScianStyle.h"
  18. #include "ScianTypes.h"
  19. #include "ScianFontSystem.h"
  20. #include "ScianWindows.h"
  21. #include "ScianDraw.h"
  22. #include "ScianTextBoxes.h"
  23.  
  24. #ifdef GRAPHICS
  25. #include "ScianPalatino18.h"
  26. #include "ScianTitleFont.h"
  27.  
  28. #define NRASTERFONTS    4    /* NOT including system font or icon fonts */
  29. #define SCIANTITLE    1
  30. #define MAXFONTSUSED    10  /* max different fonts in window (for PS drawing) */
  31.  
  32. #endif
  33.  
  34. #ifndef TABWID
  35. #define TABWID    4    /* number of 'chars' per tab stop */
  36. #endif
  37.  
  38. /*
  39.     The font system handles font manager routines, if available, as
  40.     well as raster fonts. When SetupFont is called, the font name
  41.     is first looked up using fmfindfont. If found, the font is scaled
  42.     to size and currentFontHandle is set for use by subsequent calls 
  43.     to DrawAString, StringWidth, etc. If fmfindfont fails (or if not
  44.     FONTS4D) currentFontHandle is set to NULL and the name is looked
  45.     up in the raster font name table, rasterFont[]. (The size parameter
  46.     is ignored.) If not found the system font is used.
  47.  
  48.     Note that icon fonts are not treated like text fonts, although they
  49.     are initialized here in InitFonts.
  50. */
  51.  
  52. /* globals for font system */
  53.  
  54. #ifdef GRAPHICS
  55.  
  56. char *rasterFont[NRASTERFONTS + 1];    /* table of raster font name pointers */
  57. int nFonts = 0;
  58. char **fonts;
  59. static int registeredFonts;
  60. char curFontName[64];        /* remember which font is set */
  61. int curFontSize;
  62.  
  63. #ifdef FONTS4D
  64. fmfonthandle currentFontHandle = NIL;
  65. #endif
  66.  
  67. struct fontinfo uiFontInfo[NUIFONTS] = 
  68.         {
  69.             "Helvetica-BoldOblique", 12, 0,
  70.             "Helvetica", 10, 0,
  71.                         "Helvetica", 12, 0,
  72.                         "Helvetica", 14, 0,
  73.             "Helvetica", 18, 0,
  74.             "Helvetica-Bold", 10, 0,
  75.             "Helvetica-Bold", 12, 0,
  76.                         "Helvetica-Bold", 14, 0,
  77.                         "Helvetica-Bold", 18, 0
  78.         };
  79.  
  80. #endif
  81.  
  82. char *fontsUsed[MAXFONTSUSED];    /* list of fonts used in PostScript file */
  83. int numFontsUsed = 0;        /* number of fonts used = next index */
  84. char showBuf[256];    /* string buffer for PostScript show */
  85.  
  86.  
  87. static void CountFonts(s)
  88. char *s;
  89. /*Counts the fonts*/
  90. {
  91. #ifdef GRAPHICS
  92.     ++nFonts;
  93. #endif
  94. }
  95.  
  96. static void RegisterFont(s)
  97. char *s;
  98. /*Puts the font names in a list, fonts[]*/
  99. {
  100. #ifdef GRAPHICS
  101.     fonts[registeredFonts] = Alloc(strlen(s) + 1);
  102.     strcpy(fonts[registeredFonts], s);
  103.     ++registeredFonts;
  104. #endif
  105. }
  106.  
  107. #ifdef PROTO
  108. static int CompareFonts(const void *f1, const void *f2)
  109. #else
  110. static int CompareFonts(f1, f2)
  111. void *f1;
  112. void *f2;
  113. #endif
  114. /*Compares two font names*/
  115. {
  116.     return strcmp2(*(char **) f1, *(char **) f2);
  117. }
  118.  
  119. #ifdef PROTO
  120. static void SortFonts(void)
  121. #else
  122. static void SortFonts()
  123. #endif
  124. {
  125.     /*Sorts the fonts*/
  126.  
  127.     qsort(fonts, registeredFonts, sizeof(char *), CompareFonts);
  128. }
  129.  
  130. void InitFonts(void) /*********************************** INITFONTS */
  131. {
  132. #ifdef GRAPHICS
  133.     int i;
  134. #ifdef FONTS4D
  135.     fmfonthandle fh;
  136. #endif
  137.  
  138.     nFonts = 2;
  139.  
  140. #ifdef FONTS4D
  141.     fminit();
  142.     fmenumerate(CountFonts);
  143. #endif
  144.     fonts = (char**) Alloc(sizeof(char *) * nFonts);
  145. #ifdef FONTS4D
  146.     /* register fonts for font menu */
  147.     registeredFonts = 0;
  148.     fmenumerate(RegisterFont);
  149. #endif
  150.  
  151.     /*Complete font menu with System and Palatino18*/
  152.     RegisterFont("System");
  153.     RegisterFont("Palatino18");
  154.  
  155.     SortFonts();
  156.  
  157.     rasterFont[0] = "System"; /* default */
  158.     for (i=1; i<NRASTERFONTS+1; ++i) rasterFont[i] = "\0";
  159.  
  160. #ifdef BIGFONTSOK
  161.     rasterFont[TITLEFONT] = "ScianTitle";
  162.     defrasterfont(TITLEFONT, ScianTitleFontHT, ScianTitleFontNC, ScianTitleFontchars, 
  163.             ScianTitleFontRS, (void *) ScianTitleFontrasters);
  164. #endif
  165.     rasterFont[SUBTITLEFONT] = "Palatino18";
  166.     defrasterfont(SUBTITLEFONT, palatino18HT, palatino18NC, stChars,
  167.             palatino18RS, (void *) stRasters);
  168.  
  169.     numFontsUsed = 0;
  170.     strcpy(curFontName, "System");
  171.     curFontSize = 10;
  172.  
  173. #ifdef FONTS4D
  174. /* set up fonts for user interface */
  175.     /* Regular fonts */
  176.     fh = fmfindfont(uiFontInfo[UISMALLFONT].name);
  177.     if (fh) 
  178.     {
  179.         uiFontInfo[UISMALLFONT].fontHandle = (char **)
  180.             fmscalefont(fh, uiFontInfo[UISMALLFONT].size);
  181.         uiFontInfo[UINORMALFONT].fontHandle = (char **)
  182.             fmscalefont(fh, uiFontInfo[UINORMALFONT].size);
  183.         uiFontInfo[UILARGEFONT].fontHandle = (char **)
  184.             fmscalefont(fh, uiFontInfo[UILARGEFONT].size);
  185.         uiFontInfo[UITITLEFONT].fontHandle = (char **)
  186.             fmscalefont(fh, uiFontInfo[UITITLEFONT].size);
  187.     }
  188.     /* Bold fonts */
  189.     fh = fmfindfont(uiFontInfo[UIBOLDSMALLFONT].name);
  190.     if (fh)
  191.     {
  192.         uiFontInfo[UIBOLDSMALLFONT].fontHandle = (char **)
  193.             fmscalefont(fh, uiFontInfo[UIBOLDSMALLFONT].size);
  194.         uiFontInfo[UIBOLDNORMALFONT].fontHandle = (char **)
  195.             fmscalefont(fh, uiFontInfo[UIBOLDNORMALFONT].size);
  196.         uiFontInfo[UIBOLDLARGEFONT].fontHandle = (char **)
  197.             fmscalefont(fh, uiFontInfo[UIBOLDLARGEFONT].size);
  198.         uiFontInfo[UIBOLDTITLEFONT].fontHandle = (char **)
  199.             fmscalefont(fh, uiFontInfo[UIBOLDTITLEFONT].size);
  200.     }
  201.     else
  202.     {
  203.         uiFontInfo[UIBOLDSMALLFONT].fontHandle =
  204.             uiFontInfo[UISMALLFONT].fontHandle;
  205.         uiFontInfo[UIBOLDNORMALFONT].fontHandle = 
  206.             uiFontInfo[UINORMALFONT].fontHandle;
  207.         uiFontInfo[UIBOLDLARGEFONT].fontHandle = 
  208.             uiFontInfo[UILARGEFONT].fontHandle;
  209.         uiFontInfo[UIBOLDTITLEFONT].fontHandle = 
  210.             uiFontInfo[UITITLEFONT].fontHandle;
  211.     }
  212.     /* menu font */
  213.     fh = fmfindfont(uiFontInfo[UIMENUFONT].name);
  214.     if (fh)
  215.     {
  216.         uiFontInfo[UIMENUFONT].fontHandle = (char **)
  217.             fmscalefont(fh, uiFontInfo[UIMENUFONT].size);
  218.     }
  219.     else
  220.     {
  221.         if (uiFontInfo[UIBOLDNORMALFONT].fontHandle)
  222.             uiFontInfo[UIMENUFONT].fontHandle =
  223.                 uiFontInfo[UIBOLDNORMALFONT].fontHandle;
  224.         else uiFontInfo[UIMENUFONT].fontHandle =
  225.                 uiFontInfo[UINORMALFONT].fontHandle;
  226.     }
  227. #endif
  228.  
  229. #endif
  230. }
  231.  
  232. void KillFonts(void)
  233. {
  234. #ifdef GRAPHICS
  235.     int k;
  236.     /*** free memory ***/
  237.     for (k = 0; k < nFonts; ++k)
  238.     {
  239.     Free(fonts[k]);
  240.     }
  241.     if (fonts)
  242.     {
  243.     Free(fonts);
  244.     }
  245. #endif
  246. }
  247.  
  248. #ifdef PROTO
  249. Bool SetupFont(char *name, int size)
  250. #else
  251. Bool SetupFont(name, size)
  252. char *name;
  253. int size;
  254. #endif
  255. {
  256. #ifdef GRAPHICS
  257.     int i;
  258.  
  259.     if (drawingMode == DRAW_SCREEN)
  260.     {
  261. #ifdef FONTS4D
  262.         currentFontHandle = fmfindfont(name);
  263.         if (currentFontHandle)
  264.         {
  265.             currentFontHandle = fmscalefont(currentFontHandle, size);
  266.             fmsetfont(currentFontHandle);
  267.             return true;
  268.     }
  269.         else
  270.         {
  271.             currentFontHandle = NIL;
  272.             for (i=1; i<NRASTERFONTS+1; ++i)
  273.             {
  274.                 if (strcmp(name, rasterFont[i]) != 0) continue;
  275.                 font(i);
  276.                 return true;
  277.             }
  278.             font(0);
  279.             return false;
  280.     }
  281. #else
  282.         for (i=1; i<NRASTERFONTS+1; ++i)
  283.         {
  284.             if (strcmp(name, rasterFont[i]) != 0) continue;
  285.             font(i);
  286.             return true;
  287.         }
  288.         font(0);
  289.         return false;
  290. #endif
  291.     }
  292.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  293.     {
  294.         /* see if same as current font and size */
  295.         if (strcmp(name, curFontName) == 0 && size == curFontSize) return true;
  296.     RegisterFontUsed(name);    /* add to list for PS file trailer */
  297.         strcpy(curFontName, name); /* remember this */
  298.     curFontSize = size;
  299.  
  300.         /* write PostScript to drawing file to set up font */
  301.     /* size is made larger by 2 points to adjust for screen vs printer */
  302.         fprintf(psFile, "/%s findfont %d scalefont setfont\n", name, size+2);
  303.         return true;
  304.     }
  305. #endif
  306.     return false;
  307. }
  308.  
  309. #ifdef PROTO
  310. void SetUIFont(int uiFontNum)
  311. #else
  312. void SetUIFont(uiFontNum)
  313. int uiFontNum;
  314. #endif
  315. {
  316. #ifdef GRAPHICS
  317.     if (drawingMode == DRAW_SCREEN)
  318.     {
  319. #ifdef FONTS4D
  320.     currentFontHandle = (fmfonthandle) uiFontInfo[uiFontNum].fontHandle;
  321.         fmsetfont(currentFontHandle);
  322. #else
  323.     font(0);
  324. #endif
  325.     }
  326.     else if (drawingMode == DRAW_POSTSCRIPT && psFile)
  327.     {
  328.         /* see if same as current font and size */
  329.         if (strcmp(uiFontInfo[uiFontNum].name, curFontName) == 0
  330.         && uiFontInfo[uiFontNum].size == curFontSize) return;
  331.     RegisterFontUsed(uiFontInfo[uiFontNum].name);
  332.         strcpy(curFontName, uiFontInfo[uiFontNum].name); /* remember this */
  333.     curFontSize = uiFontInfo[uiFontNum].size;
  334.  
  335.         /* write PostScript to drawing file to set up font */
  336.     /* size is made larger by 2 points to adjust for screen vs printer */
  337.         fprintf(psFile, "/%s findfont %d scalefont setfont\n", 
  338.         uiFontInfo[uiFontNum].name, uiFontInfo[uiFontNum].size+2);
  339.     }
  340. #endif
  341. }
  342.  
  343. #ifdef PROTO
  344. void RegisterFontUsed(char *name)
  345. #else
  346. void RegisterFontUsed(name)
  347. char *name;
  348. #endif
  349. {
  350. /* for PostScript file output--makes list of fonts used for trailer */
  351. #ifdef GRAPHICS
  352.     int i;
  353.  
  354.     /* check list of fonts used */
  355.     for (i = 0; i < numFontsUsed; ++i)
  356.     {
  357.         if (strcmp(name, fontsUsed[i]) == 0) return;
  358.     }
  359.     if (numFontsUsed >= MAXFONTSUSED)
  360.     {
  361.         ReportError("RegisterFontUsed","Too many fonts!");
  362.         return;
  363.     }
  364.     fontsUsed[numFontsUsed] = Alloc(strlen(name) + 1);
  365.     if (fontsUsed[numFontsUsed])
  366.     {
  367.          strcpy(fontsUsed[numFontsUsed], name);
  368.          ++numFontsUsed;
  369.     }
  370.     else OMErr();
  371. #endif
  372.     return;
  373. }
  374.  
  375.  
  376. #ifdef PROTO
  377. int ChrWidth(char c)
  378. #else
  379. int ChrWidth(c)
  380. char c;
  381. #endif
  382. {
  383. #ifdef GRAPHICS
  384.     if (c < ' ') return 0;
  385. #ifdef FONTS4D
  386.     if (currentFontHandle)
  387.     {
  388.         return fmgetchrwidth(currentFontHandle, c);
  389.     }
  390.     else
  391.     {
  392.         char buf[2];
  393.  
  394.         buf[0] = c;
  395.         buf[1] = '\0';
  396.         return strwidth(buf);
  397.     }
  398. #else
  399.     {    char buf[2];
  400.  
  401.     buf[0] = c;
  402.     buf[1] = '\0';
  403.     return strwidth(buf);
  404.     }
  405. #endif
  406. #else
  407.     return 0;
  408. #endif
  409. }
  410.  
  411. #ifdef PROTO
  412. int StrWidth(char *s)
  413. #else
  414. int StrWidth(s)
  415. char *s;
  416. #endif
  417. /* handles tabs in string */
  418. {
  419. #ifdef GRAPHICS
  420.     int nTabs=0;
  421.     char *t=s;
  422.  
  423.     while (*t)
  424.     {
  425.         if (*t++ == '\t')
  426.         {
  427.             s = t; /* point to char following tab */
  428.             ++nTabs;   /* incr tab count */
  429.         }
  430.     }
  431.     /* now return the indent plus the length of the string following last tab */
  432. #ifdef FONTS4D
  433.     if (currentFontHandle)
  434.     {
  435.         return nTabs*TABWID*ChrWidth('0') + fmgetstrwidth(currentFontHandle, s);
  436.     }
  437.     else
  438.     {
  439.         return nTabs*TABWID*ChrWidth('0') + strwidth(s);
  440.     }
  441. #else
  442.     return nTabs*TABWID*ChrWidth('0') + strwidth(s);
  443. #endif
  444. #else
  445.     return 0;
  446. #endif
  447. }
  448.  
  449. #ifdef PROTO
  450. char *show(char *s)
  451. #else
  452. char *show(s)
  453. char *s;
  454. #endif
  455. {
  456.     /*
  457.      * Process any special characters in string for PostScript show.
  458.      */
  459.  
  460.     char *p = showBuf;
  461.     
  462.     while (*s)
  463.     {
  464.     if (*s == '(' || *s == ')' || *s == '\\') *p++ = '\\';
  465.     *p++ = *s++;
  466.     }
  467.     *p = '\0';
  468.     return showBuf;
  469. }
  470.  
  471. #ifdef PROTO
  472. void DrawAString(int align, long x, long y, char *s)
  473. #else
  474. void DrawAString(align, x, y, s)
  475. int align;
  476. long x, y;
  477. char *s;
  478. #endif
  479. {
  480. #ifdef GRAPHICS
  481.     int left, right, bottom, top;
  482.     int xx, yy, dxx, dyy;
  483.     
  484.     if (drawingMode == DRAW_SCREEN)
  485.     {
  486.     /* find starting point of string */
  487.     switch (align)
  488.     {
  489.         case RIGHTALIGN:
  490.             x -= StrWidth(s);
  491.             break;
  492.  
  493.         case CENTERALIGN:
  494.             x -= StrWidth(s)/2;
  495.             break;
  496.  
  497.         case LEFTALIGN:
  498.         default:
  499.             break;
  500.         }
  501.  
  502.     /* check to see if string starts out of window */
  503.     GetWindowBounds(&left, &right, &bottom, &top);
  504.     CurOffset(&xx, &yy);
  505.     GetWindowOrigin(&dxx, &dyy);
  506.     left -= xx - dxx;
  507.     
  508.     /* trim string if necessary */
  509.     while (x < left)
  510.     {
  511.         if (*s == '\0') return;
  512.         x += ChrWidth(*s++);
  513.     }
  514.     cmov2i(x, y);
  515.     
  516. #ifdef FONTS4D
  517.     if (currentFontHandle)
  518.     {
  519.         fmprstr(s);
  520.     }
  521.     else
  522.     {
  523.         charstr(s);
  524.     }
  525. #else
  526.     charstr(s);
  527. #endif
  528.     }
  529.     else if (drawingMode == DRAW_POSTSCRIPT && psFile && *s != '\0')
  530.     {
  531.     /* write PostScript to file */
  532.     fprintf(psFile, "%f setgray\n", PSColor());
  533.     switch (align)
  534.     {
  535.         case RIGHTALIGN:
  536.             fprintf(psFile,
  537.     "(%s) dup %d exch stringwidth pop sub %d moveto show\n", show(s), x, y);
  538.             break;
  539.  
  540.         case CENTERALIGN:
  541.             fprintf(psFile,
  542.     "(%s) dup %d exch stringwidth pop 2 div sub %d moveto show\n", show(s), x, y);
  543.             break;
  544.  
  545.         case LEFTALIGN:
  546.         default:
  547.                 fprintf(psFile, "%d %d moveto (%s) show\n", x, y, show(s));
  548.             break;
  549.     }
  550.     }
  551. #endif
  552. }
  553.